import simplejson
import urllib2
import datetime
import calendar
import pytz
from time import sleep

from twisted.python import log
from smap import driver

class WunderGroundHistory(driver.SmapDriver):
    def setup(self, opts):
        self.url = opts.get("Address", 
                            "http://api.wunderground.com/api/b2385f4fbadf3573/history_")
        self.start_date = opts.get("start_date", '20111101')
        self.end_date = opts.get("end_date", '20111103')
        self.q_type = opts.get("q_type", '/q/CA/San_Francisco.json') #query type (refer to wunderground api documentation)      
        self.add_timeseries("/wind_dir", "deg")
        self.add_timeseries("/wind_speed", "m/s", data_type="double")
        self.add_timeseries("/wind_gust", "m/s", data_type="double") 
        self.add_timeseries("/humidity", "rh")
        self.add_timeseries("/temperature", "F", data_type="double") 
        self.add_timeseries("/mean_wind_speed", "m/s", data_type="double") 
        self.add_timeseries("/mean_humidity", "rh")
        self.add_timeseries("/max_humidity", "rh")
        self.add_timeseries("/min_humidity", "rh")
        self.add_timeseries("/mean_temp", "F", data_type="double")
        self.add_timeseries("/max_temp", "F", data_type="double")
        self.add_timeseries("/min_temp", "F", data_type="double")    
        self.add_timeseries("/mean_dew_point", "F", data_type="double")   

    def start(self):
        self.load()
    
    def load(self, *args):
        py_sdate = datetime.datetime.strptime(self.start_date,'%Y%m%d')
        d = py_sdate
        py_edate = datetime.datetime.strptime(self.end_date,'%Y%m%d')
        delta = datetime.timedelta(days=1)
        while d < py_edate:
            try:
                url = self.url + d.strftime('%Y%m%d') + self.q_type
                fh = urllib2.urlopen(url, timeout=10)
            except urllib2.URLError, e:
                log.err("URLError getting reading: [%s]: %s" % (url, str(e)))
                return
            except urllib2.HTTPError, e:
                log.err("HTTP Error: [%s]: %s" % (url, str(e)))
                return
    
            try:
                json_d = simplejson.load(fh)
                fh.close()
            except e:
                log.err("Exception parsing json [%s]: %s" % (url, str(e)))
                return
            try:
                reading_date = json_d['history']['utcdate']    
                reading_time = int(calendar.timegm(datetime.datetime(int(reading_date['year']),int(reading_date['mon']),int(reading_date['mday']),int(reading_date['hour']),int(reading_date['min']),0,0,pytz.utc).utctimetuple()))
            except Exception, e:
                log.err("Exception finding time [%s]: %s" % (url, str(e)))
                return
            log.err(url)
            #first add daily summary data
            if json_d['history']['dailysummary'][0]['meanwindspdi'] != '': self.add('/mean_wind_speed', reading_time, float(json_d['history']['dailysummary'][0]['meanwindspdi'])) 
            if json_d['history']['dailysummary'][0]['humidity'] != '': self.add('/mean_humidity', reading_time, int(json_d['history']['dailysummary'][0]['humidity']))
            if json_d['history']['dailysummary'][0]['maxhumidity'] != '': self.add('/max_humidity', reading_time, int(json_d['history']['dailysummary'][0]['maxhumidity']))
            if json_d['history']['dailysummary'][0]['minhumidity'] != '': self.add('/min_humidity', reading_time, int(json_d['history']['dailysummary'][0]['minhumidity']))
            if json_d['history']['dailysummary'][0]['meantempi'] != '': self.add('/mean_temp', reading_time, float(json_d['history']['dailysummary'][0]['meantempi']))
            if json_d['history']['dailysummary'][0]['maxtempi'] != '': self.add('/max_temp', reading_time, float(json_d['history']['dailysummary'][0]['maxtempi']))
            if json_d['history']['dailysummary'][0]['mintempi'] != '': self.add('/min_temp', reading_time, float(json_d['history']['dailysummary'][0]['mintempi']))
            if json_d['history']['dailysummary'][0]['meandewpti'] != '': self.add('/mean_dew_point', reading_time, float(json_d['history']['dailysummary'][0]['meandewpti']))
            #then add whatever observations are there
            for observation in json_d['history']['observations']:
                reading_date = observation['utcdate']
                reading_time = int(calendar.timegm(datetime.datetime(int(reading_date['year']),int(reading_date['mon']),int(reading_date['mday']),int(reading_date['hour']),int(reading_date['min']),0,0,pytz.utc).utctimetuple()))
                if observation['wdird'] != '': self.add('/wind_dir', reading_time, int(observation['wdird'])) 
                if observation['wspdi'] != '': self.add('/wind_speed', reading_time, float(observation['wspdi']))
                if observation['wgusti'] != '': self.add('/wind_gust', reading_time, float(observation['wgusti']))
                if observation['hum'] != '': self.add('/humidity', reading_time, int(observation['hum']))
                if observation['tempi'] != '': self.add('/temperature', reading_time, float(observation['tempi']))
            d+=delta
            sleep(10) #wait ten seconds so that you don't do too many requests per minute and violate wunderground api rules
